package com.huike.report.service.impl;



import com.huike.business.mapper.TbBusinessMapper;
import com.huike.clues.domain.TbActivity;
import com.huike.clues.domain.TbAssignRecord;
import com.huike.clues.domain.TbClue;
import com.huike.clues.domain.vo.IndexStatisticsVo;
import com.huike.clues.mapper.*;
import com.huike.common.core.domain.entity.BusinessChangeStatistics;
import com.huike.common.core.domain.entity.SysDept;
import com.huike.common.utils.DateUtils;
import com.huike.common.utils.SecurityUtils;
import com.huike.contract.domain.TbContract;
import com.huike.contract.mapper.TbContractMapper;
import com.huike.report.domain.ClueData;
import com.huike.report.domain.vo.*;
import com.huike.report.mapper.ReportMapper;
import com.huike.report.service.IReportService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.util.*;

@Service
public class ReportServiceImpl implements IReportService {

    @Autowired(required = false)
    private TbContractMapper contractMapper;
    @Autowired(required = false)
    private SysDictDataMapper sysDictDataMapper;
    @Autowired(required = false)
    private TbClueMapper clueMapper;
    @Autowired(required = false)
    private TbActivityMapper activityMapper;
    @Autowired(required = false)
    private SysDeptMapper deptMapper;
    @Autowired(required = false)
    private TbAssignRecordMapper assignRecordMapper;
    @Autowired(required = false)
    private ReportMapper reportMapper;
    @Autowired(required = false)
    private TbBusinessMapper businessMapper;



    /**
     * 渠道统计
     */
    @Override
    public List<Map<String, Object>> chanelStatistics(String beginCreateTime, String endCreateTime) {
        List<Map<String, Object>> data= contractMapper.chanelStatistics(beginCreateTime,endCreateTime);
        for (Map<String, Object> datum : data) {
            String subjectValue= (String) datum.get("channel");
            String lable=  sysDictDataMapper.selectDictLabel("clues_item",subjectValue);
            datum.put("channel",lable);
        }
        return data;
    }

    @Override
    public List<TbContract> contractReportList(TbContract tbContract) {
       return contractMapper.selectTbContractList(tbContract);
    }


    @Override
    public List<Map<String, Object>> activityStatistics(String beginCreateTime, String endCreateTime) {
        List<Map<String, Object>> data= contractMapper.activityStatistics(beginCreateTime,endCreateTime);
        for (Map<String, Object> datum : data) {
            Long activityId= (Long) datum.get("activity_id");
            TbActivity tbActivity = activityMapper.selectTbActivityById(activityId);
            if(tbActivity==null){
                datum.put("activity", "其他");
            }else{
                datum.put("activity", tbActivity.getName());
            }
        }
        return data;
    }

    /**
     * 按照部门统计销售
     * @param beginCreateTime
     * @param endCreateTime
     * @return
     */
    @Override
    public List<Map<String, Object>> deptStatisticsList(String beginCreateTime, String endCreateTime) {
        List<Map<String, Object>> data= contractMapper.deptStatistics(beginCreateTime,endCreateTime);
        for (Map<String, Object> datum : data) {
            Long deptId= (Long) datum.get("dept_id");
            if(deptId!=null){
                SysDept dept= deptMapper.selectDeptById(deptId);
                datum.put("deptName", dept.getDeptName());
            }
        }
        return data;
    }


    /**
     * 按照渠道统计销售
     * @param beginCreateTime
     * @param endCreateTime
     * @return
     */
    @Override
    public List<Map<String, Object>> channelStatisticsList(String beginCreateTime, String endCreateTime) {
        List<Map<String, Object>> data= contractMapper.channelStatistics(beginCreateTime,endCreateTime);
        for (Map<String, Object> datum : data) {
            String subjectValue= (String) datum.get("channel");
            if(subjectValue!=null){
                String lable=  sysDictDataMapper.selectDictLabel("clues_item",subjectValue);
                datum.put("channel",lable);
            }
        }
        return data;
    }


    /**
     * 按照归属人统计销售
     * @param beginCreateTime
     * @param endCreateTime
     * @return
     */
    @Override
    public List<Map<String, Object>> ownerShipStatisticsList(String beginCreateTime, String endCreateTime) {
       return  contractMapper.ownerShipStatistics(beginCreateTime,endCreateTime);
    }


    @Override
    public List<TbClue> cluesStatisticsList(TbClue clue) {
        return clueMapper.selectTbClueForReport(clue);
    }

    @Override
    public List<ActivityStatisticsVo> activityStatisticsList(TbActivity query) {
        query.setStatus("2");
        List<TbActivity> activities= activityMapper.selectTbActivityList(query);
        Map<String, Object> timeMap = query.getParams();
        List<ActivityStatisticsVo> list=new ArrayList<>();
        for (TbActivity activity : activities) {
            ActivityStatisticsVo dto = new ActivityStatisticsVo();
            BeanUtils.copyProperties(activity, dto);
            TbClue tbClue = new TbClue();
            tbClue.setActivityId(activity.getId());
            tbClue.setChannel(activity.getChannel());
            tbClue.setParams(timeMap);
            Map<String, Object> clueCount = clueMapper.countByActivity(tbClue);
            if (clueCount != null) {
                dto.setCluesNum(Integer.parseInt(clueCount.get("total").toString()));
                if(clueCount.get("falseClues")!=null){
                    dto.setFalseCluesNum(Integer.parseInt(clueCount.get("falseClues").toString()));
                }
                if (clueCount.get("toBusiness") != null) {
                    dto.setBusinessNum(Integer.parseInt(clueCount.get("toBusiness").toString()));
                }
            }
            TbContract tbContract = new TbContract();
            tbContract.setChannel(activity.getChannel());
            tbContract.setActivityId(activity.getId());
            tbContract.setParams(timeMap);
            Map<String, Object> contractCount = contractMapper.countByActivity(tbContract);
            if (contractCount != null) {
                dto.setCustomersNum(Integer.parseInt(contractCount.get("customersNum").toString()));
                if(contractCount.get("amount")==null) {
                	dto.setAmount(0d);
                }else {
                	dto.setAmount((Double) contractCount.get("amount"));
                }
                if(contractCount.get("cost")==null) {
                	dto.setCost(0d);
                }else {
                	dto.setCost((Double) contractCount.get("cost"));
                }
                
            }
            list.add(dto);
        }
        return list;
    }


    @Override
    public IndexVo getIndex(IndexStatisticsVo request) {
        Long deptId= request.getDeptId();
        TbAssignRecord tbAssignRecord=new TbAssignRecord();
        tbAssignRecord.setLatest("1");
        assignRecordMapper.selectAssignRecordList(tbAssignRecord);
        return null;
    }


    /**
     * 获取首页基本数据
     * @param beginCreateTime
     * @param endCreateTime
     * @return
     */
    @Override
    public IndexBaseInfoVO getBaseInfo(String beginCreateTime, String endCreateTime) {
        //1 构建一个空的结果集对象
        IndexBaseInfoVO result = new IndexBaseInfoVO();
        //2 封装结果集属性
        // 2.1 由于查询需要用到用户名 调用工具类获取用户名
        String username = SecurityUtils.getUsername();
        // 2.2 开始查询第一个属性 线索数量
        result.setCluesNum(reportMapper.getCluesNum(beginCreateTime, endCreateTime, username));
        // 2.3 开始查询第一个属性 商机数量
        result.setBusinessNum(reportMapper.getBusinessNum(beginCreateTime, endCreateTime, username));
        // 2.4 开始查询第一个属性 合同数量
        result.setContractNum(reportMapper.getContractNum(beginCreateTime, endCreateTime, username));
        // 2.5 开始查询第一个属性 销售金额数量
        result.setSalesAmount(reportMapper.getSalesAmount(beginCreateTime, endCreateTime, username)==null?0: reportMapper.getSalesAmount(beginCreateTime, endCreateTime, username));
        //5 返回结果集对象
        return result;
    }

    /**
     * 获取今日简报数据
     * @param beginCreateTime
     * @param endCreateTime
     * @return
     */
    @Override
    public ToDayVo getTodayInfo(String beginCreateTime, String endCreateTime) {
        //1 构建一个空的结果集对象
        ToDayVo result = new ToDayVo();
        //2 封装结果集属性
        // 2.1 由于查询需要用到用户名 调用工具类获取用户名
        String username = SecurityUtils.getUsername();
        // 2.2 开始查询第一个属性 线索数量   合同不管状态不能复用
        result.setTodayCluesNum(reportMapper.getTodayCluesNum(beginCreateTime, endCreateTime, username));
        // 2.3 开始查询第一个属性 商机数量  合同不管状态不能复用
        result.setTodayBusinessNum(reportMapper.getTodayBusinessNum(beginCreateTime, endCreateTime, username));
        // 2.4 开始查询第一个属性 合同数量 合同不管状态不能复用
        result.setTodayContractNum(reportMapper.getTodayContractNum(beginCreateTime, endCreateTime, username));
        // 2.5 开始查询第一个属性 销售金额数量
        result.setTodaySalesAmount(reportMapper.getTodaySalesAmount(beginCreateTime, endCreateTime, username)==null?0: reportMapper.getSalesAmount(beginCreateTime, endCreateTime, username));
        //5 返回结果集对象
        return result;
    }

    /**
     * 获取待办数据
     * @param beginCreateTime
     * @param endCreateTime
     * @return
     */
    @Override
    public ToDoVo getToInfo(String beginCreateTime, String endCreateTime) {
        //1 构建一个空的结果集对象
        ToDoVo result = new ToDoVo();
        //2 封装结果集属性
        // 2.1 由于查询需要用到用户名 调用工具类获取用户名
        String username = SecurityUtils.getUsername();
        // 2.2 开始查询第一个属性 待跟进线索数量
        result.setTofollowedCluesNum(reportMapper.getToFollowCluesNum(beginCreateTime,endCreateTime,username));
        // 2.3 开始查询第二个属性 待分配的线索
        result.setToallocatedCluesNum(reportMapper.getToTransferCluesNum(beginCreateTime,endCreateTime,username));
        // 2.4 开始查询第三个属性 待跟进的商机数量
        result.setTofollowedBusinessNum(reportMapper.getToFollowBusinessNum(beginCreateTime,endCreateTime,username));
        // 2.5 开始查询第一个属性 销售金额数量  复用
        result.setToallocatedBusinessNum(reportMapper.getToTransferBusinessNum(beginCreateTime, endCreateTime, username));
        //5 返回结果集对象
        return result;
    }

    /**
     * 每日新增线索折线图
     * @param beginCreateTime
     * @param endCreateTime
     * @return
     */
    @Override
    public EveryDayNewClueVo salesStatistics(String beginCreateTime, String endCreateTime) {
        //1.查找出当前用户  由于查询需要用到用户名 调用工具类获取用户名
        String username = SecurityUtils.getUsername();
        //2.计算出有多少天
            //1.调用工具类将两个字符串日期转化为日期对象
        Date start = DateUtils.parseDate(beginCreateTime);
        Date end = DateUtils.parseDate(endCreateTime);
            //2.调用工具类获得全部天数
        List<Date> allDay = DateUtils.getAllDay(start, end);
        //日期格式化
        SimpleDateFormat everyDay = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat startFormat = new SimpleDateFormat("yyyy-MM-dd 00:00:00");
        SimpleDateFormat endFormat = new SimpleDateFormat("yyyy-MM-dd 23:59:59");
        //封装结果的
        String[] xAxis = new String[allDay.size()];
        Integer[] add = new Integer[allDay.size()];
        Integer[] all = new Integer[allDay.size()];
        //循环查询
        for (int i = 0; i < allDay.size(); i++) {
            //当前日期
            String nowDay = everyDay.format(allDay.get(i));
            //设置开始
            String startTime = startFormat.format(allDay.get(i));
            String endTime = endFormat.format(allDay.get(i));
            //查询这一天的新增线索
            Integer todayCluesNum = reportMapper.getTodayCluesNum(startTime, endTime, username);
            //获得当前线索总数量
            int allClues = clueMapper.getAllClues(endTime);
            //封装数据
            xAxis[i] = nowDay;
            add[i] = todayCluesNum;
            all[i] = allClues;
        }
        //分装返回的结果
        EveryDayNewClueVo everyDayNewClueVo = new EveryDayNewClueVo();
        ClueData dataAdd = new ClueData();
        ClueData dataAll = new ClueData();
        everyDayNewClueVo.setxAxis(Arrays.asList(xAxis));
        dataAdd.setName("新增线索数量");
        dataAdd.setData(add);
        dataAll.setName("线索总数量");
        dataAll.setData(all);
        List<ClueData> series = new ArrayList<>();
        series.add(dataAdd);
        series.add(dataAll);
        everyDayNewClueVo.setSeries(series);
        return everyDayNewClueVo;
    }

    /**
     * 统计分析-客户统计-学科客户分布饼图
     * @param
     * @return
     */
    public Map<String, Integer>[] subjectStatistics(String beginCreateTime, String endCreateTime){
        //设置各个学科  查询各个学科的合同数量用map集合封装数据
        return contractMapper.selectContractNumberBySubjectCode(beginCreateTime, endCreateTime);
    }

    /**
     * 统计分析--线索统计--线索转化率漏斗图
     * @param beginCreateTime 开始时间
     * @param endCreateTime 结算时间
     */
    public GetVulnerabilityMapVo getVulnerabilityMap(String beginCreateTime, String endCreateTime){
        GetVulnerabilityMapVo result = new GetVulnerabilityMapVo();
        //查询全部线索
        Integer allCluesNum = clueMapper.selectClueNum(beginCreateTime, endCreateTime, null);
        //查询有效线索
        Integer effectiveCluesNum = clueMapper.selectClueNum(beginCreateTime, endCreateTime, 6);
        //查询全部商机
        Integer allBusiness = businessMapper.selectBusinessNumByTime(beginCreateTime,endCreateTime, null);
        //插询全部客户
        Integer contractNums = contractMapper.contractNums(beginCreateTime, endCreateTime);
        result.setCluesNums(allCluesNum);
        result.setEffectiveCluesNums(effectiveCluesNum);
        result.setBusinessNums(allBusiness);
        result.setContractNums(contractNums);
        return result;
    }

    /**
     * 首页--商机转化龙虎榜接口
     * @param beginCreateTime 开始时间
     * @param endCreateTime 结算时间
     */
    public BusinessChangeStatistics[] businessChangeStatistics(String beginCreateTime, String endCreateTime){
        BusinessChangeStatistics[] results = businessMapper.selectEveryUserBusinessChangeNum(beginCreateTime, endCreateTime);
        //查询全部由商机数  用来计算转化率
        Integer allBusinessNum = businessMapper.selectBusinessNumByTime(beginCreateTime, endCreateTime,null);
        if(allBusinessNum!=0) {
            //总条数转化为BigDecimal
            BigDecimal all = new BigDecimal(allBusinessNum);
            //遍历计算转化率
            for (BusinessChangeStatistics result : results) {
                //计算转化率
                //转化的条数
                BigDecimal num = new BigDecimal(result.getNum());
                //转化率  BigDecimal四舍五入保留4位
                BigDecimal divide = num.divide(all, 4, BigDecimal.ROUND_HALF_DOWN);
                double radio = divide.doubleValue() * 100;
                result.setRadio(radio);
            }
        }
        return results;
    }

    /**
     * 首页--线索转化龙虎榜接口
     * @param beginCreateTime 开始时间
     * @param endCreateTime 结算时间
     */
    public BusinessChangeStatistics[] salesStatistic(String beginCreateTime, String endCreateTime) {
        //查找出每个人转化的线索数量
        BusinessChangeStatistics[] results = clueMapper.selectEverySalesStatistic(beginCreateTime, endCreateTime);
        //查询全部的线索
        Integer clueNum = clueMapper.selectClueNum(beginCreateTime, endCreateTime, null);
        if(clueNum!=0) {
            //转化为bigDecimal
            BigDecimal all = new BigDecimal(clueNum);
            //循环为每一个人计算转化率
            for (BusinessChangeStatistics result : results) {
                //每个人转化的商机数量
                Integer resultNum = result.getNum();
                BigDecimal everyOne = new BigDecimal(resultNum);
                //计算转化率
                BigDecimal divide = everyOne.divide(all, 4, RoundingMode.HALF_UP);
                double radio = divide.doubleValue() * 100;
                result.setRadio(radio);
            }
        }
        return results;
    }
}